# ui/download_window.py - 修复版本
import tkinter as tk
from tkinter import ttk, messagebox
from pathlib import Path
from typing import List, Callable, Deque
from collections import deque
import threading

from models.download_file import DownloadFile
from models.package_info import PackageInfo
from ui.search_components import SearchBar, SearchManager
from ui.dialogs import show_create_package_dialog, show_edit_package_dialog
from ui.version_dialogs import VersionDialogs
from logger.logger import get_logger

class ClosableNotebook(ttk.Notebook):
    """可关闭的Notebook组件 - 修复版本"""
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bind("<ButtonPress-1>", self._on_button_press)
    
    def _on_button_press(self, event):
        """处理鼠标按下事件"""
        # 识别点击的元素
        element = self.identify(event.x, event.y)
        
        # 如果点击的是标签
        if element == "label":
            index = self.index(f"@{event.x},{event.y}")
            tab_text = self.tab(index, "text")
            
            # 检查是否点击了关闭区域（标签文本末尾的×）
            if " ×" in tab_text:
                # 简单判断：如果点击位置在标签的右半部分，认为是点击关闭
                tab_bbox = self.bbox(index)
                if tab_bbox:
                    tab_right = tab_bbox[0] + tab_bbox[2]
                    if event.x > tab_right - 20:  # 右边缘20像素内认为是关闭区域
                        self.forget(index)
                        return "break"

class DownloadWindow:
    """下载窗口 - 修复版本"""
    
    def __init__(self, root, config, download_manager, auth_manager):
        self.root = root
        self.config = config
        self.download_manager = download_manager
        self.auth_manager = auth_manager
        self.logger = get_logger(config)
        
        # 初始化组件
        self.search_manager = SearchManager(download_manager)
        self.version_dialogs = VersionDialogs(root, config, download_manager, auth_manager)
        
        # 页面历史缓存（最多16个）
        self.page_history: Deque[str] = deque(maxlen=16)
        
        # 下载任务管理
        self.download_tasks = []
        self.completed_tasks = []
        
        # 创建窗口
        self.create_window()
        
        # 初始同步
        self.sync_data()
    
    def create_window(self):
        """创建下载窗口"""
        self.window = tk.Toplevel(self.root)
        self.window.title("文件下载管理器")
        self.window.geometry("1000x700")
        
        # 创建主框架
        main_frame = ttk.Frame(self.window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 创建导航栏
        self.create_navigation_bar(main_frame)
        
        # 创建内容区域
        self.create_content_area(main_frame)
        
        # 初始显示选择下载页面
        self.show_select_download_page()
    
    def create_navigation_bar(self, parent):
        """创建导航栏"""
        nav_frame = ttk.Frame(parent)
        nav_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 返回按钮
        self.back_button = ttk.Button(
            nav_frame,
            text="← 返回",
            command=self.go_back,
            state="disabled"
        )
        self.back_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 页面切换按钮
        self.select_download_button = ttk.Button(
            nav_frame,
            text="选择下载",
            command=self.show_select_download_page
        )
        self.select_download_button.pack(side=tk.LEFT, padx=(0, 10))
        
        self.download_status_button = ttk.Button(
            nav_frame,
            text="下载状态",
            command=self.show_download_status_page
        )
        self.download_status_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 新建按钮 - 根据上下文变化
        self.new_button = ttk.Button(
            nav_frame,
            text="新建",
            command=self.on_new_clicked
        )
        self.new_button.pack(side=tk.LEFT)
    
    def on_new_clicked(self):
        """新建按钮点击事件 - 根据当前页面决定行为"""
        current_index = self.notebook.index("current")
        if current_index == 0:  # 选择下载页面
            self.show_create_new_dialog()
        elif current_index == 1:  # 下载状态页面
            # 在下载状态页面，新建按钮无操作
            messagebox.showinfo("提示", "在下载状态页面无法创建新内容")
        else:
            # 包详情页面 - 新建版本
            current_tab = self.notebook.tab(current_index, "text")
            if " ×" in current_tab:
                package_name = current_tab.replace(" ×", "")
                self.create_new_version(package_name)
    
    def create_content_area(self, parent):
        """创建内容区域"""
        # 创建可关闭的笔记本（选项卡）
        self.notebook = ClosableNotebook(parent)
        self.notebook.pack(fill=tk.BOTH, expand=True)
        
        # 选择下载页面 - 不可关闭
        self.select_download_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.select_download_frame, text="选择下载")
        
        # 下载状态页面 - 不可关闭
        self.download_status_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.download_status_frame, text="下载状态")
    
    def go_back(self):
        """返回上一个页面"""
        if len(self.page_history) > 1:
            # 移除当前页面
            current_page = self.page_history.pop()
            # 获取上一个页面
            previous_page = self.page_history[-1]
            
            # 切换到上一个页面
            if previous_page == "select_download":
                self.show_select_download_page()
            elif previous_page == "download_status":
                self.show_download_status_page()
            else:
                # 包详情页面
                self.show_package_detail_page(previous_page, from_back=True)
            
            # 更新返回按钮状态
            self.update_back_button_state()
    
    def update_back_button_state(self):
        """更新返回按钮状态"""
        if len(self.page_history) > 1:
            self.back_button.config(state="normal")
        else:
            self.back_button.config(state="disabled")
    
    def push_to_history(self, page_name: str):
        """将页面推入历史记录"""
        # 如果已经在历史记录中，先移除
        if page_name in self.page_history:
            self.page_history.remove(page_name)
        
        self.page_history.append(page_name)
        self.update_back_button_state()
    
    def show_select_download_page(self):
        """显示选择下载页面"""
        # 添加到历史记录
        self.push_to_history("select_download")
        
        # 显示选择下载页面
        self.notebook.select(0)
        
        # 刷新文件列表
        self.refresh_file_list()
    
    def show_download_status_page(self):
        """显示下载状态页面"""
        # 添加到历史记录
        self.push_to_history("download_status")
        
        # 显示下载状态页面
        self.notebook.select(1)
        
        # 刷新下载状态
        self.refresh_download_status()
    
    def show_create_new_dialog(self):
        """显示新建文件包对话框"""
        show_create_package_dialog(
            self.root, self.config, self.download_manager, self.auth_manager,
            self.on_package_created
        )
    
    def on_package_created(self, success: bool):
        """包创建回调"""
        if success:
            self.refresh_file_list()
    
    def refresh_file_list(self, keyword: str = ""):
        """刷新文件列表"""
        self.logger.info("开始刷新文件列表...")
        
        # 清空现有内容
        for widget in self.select_download_frame.winfo_children():
            widget.destroy()
        
        # 获取文件列表
        file_list = self.download_manager.get_file_list()
        self.logger.info(f"获取到文件列表: {len(file_list)} 个项目")
        
        if keyword:
            file_list = self.search_manager.search_files(keyword, file_list)
            self.logger.info(f"搜索后文件列表: {len(file_list)} 个项目")
        
        if not file_list:
            # 显示空状态
            empty_frame = ttk.Frame(self.select_download_frame)
            empty_frame.pack(expand=True)
            
            ttk.Label(
                empty_frame, 
                text="没有找到文件",
                font=("Arial", 12)
            ).pack(expand=True)
            return
        
        # 创建搜索栏
        search_bar = SearchBar(
            self.select_download_frame,
            search_callback=self.refresh_file_list,
            placeholder="搜索文件包..."
        )
        search_bar.get_frame().pack(fill=tk.X, pady=(0, 10))
        
        # 创建滚动框架
        container_frame = ttk.Frame(self.select_download_frame)
        container_frame.pack(fill=tk.BOTH, expand=True)
        
        canvas = tk.Canvas(container_frame)
        scrollbar = ttk.Scrollbar(container_frame, orient=tk.VERTICAL, command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        # 显示文件列表
        for i, file_info in enumerate(file_list):
            self.logger.info(f"创建文件项: {file_info.name}")
            self.create_file_item(scrollable_frame, file_info, i)
        
        # 布局
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    def create_file_item(self, parent, file_info: DownloadFile, index: int):
        """创建文件项"""
        item_frame = ttk.Frame(parent, relief=tk.RAISED, borderwidth=1)
        item_frame.pack(fill=tk.X, padx=5, pady=2)
        
        # 左侧：预览图像
        image_frame = ttk.Frame(item_frame, width=80, height=80)
        image_frame.pack(side=tk.LEFT, padx=5, pady=5)
        image_frame.pack_propagate(False)
        
        # 显示占位符，稍后异步加载图片
        placeholder_label = ttk.Label(image_frame, text="图片", font=("Arial", 8))
        placeholder_label.pack(expand=True)
        
        # 异步加载图片
        self.load_package_image_async(file_info.name, image_frame, placeholder_label)
        
        # 中间：文件信息
        info_frame = ttk.Frame(item_frame)
        info_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5, pady=5)
        
        # 文件名
        name_label = ttk.Label(info_frame, text=file_info.name, font=("Arial", 12, "bold"))
        name_label.pack(anchor=tk.W)
        
        # 文件简述
        brief_label = ttk.Label(info_frame, text=file_info.brief, font=("Arial", 10))
        brief_label.pack(anchor=tk.W)
        
        # 更新时间
        time_label = ttk.Label(info_frame, text=f"更新: {file_info.updated_time}", font=("Arial", 9))
        time_label.pack(anchor=tk.W)
        
        # 右侧：操作按钮
        button_frame = ttk.Frame(item_frame)
        button_frame.pack(side=tk.RIGHT, padx=5, pady=5)
        
        # 查看按钮
        enter_button = ttk.Button(
            button_frame,
            text="查看",
            command=lambda name=file_info.name: self.show_package_detail_page(name)
        )
        enter_button.pack(pady=2, fill=tk.X)
        
        # 更改按钮（需要权限）
        if self.auth_manager.has_upload_permission():
            edit_button = ttk.Button(
                button_frame,
                text="更改",
                command=lambda name=file_info.name: self.show_edit_package_dialog(name)
            )
            edit_button.pack(pady=2, fill=tk.X)
    
    def load_package_image_async(self, package_name: str, image_frame: ttk.Frame, placeholder_label):
        """异步加载包图片"""
        def load_image():
            try:
                # 尝试从缓存获取图片
                from core.cache_manager import CacheManager
                cache_manager = CacheManager(self.config, self.download_manager)
                image_path = cache_manager.get_cached_image_path(package_name)
                
                if image_path and image_path.exists():
                    try:
                        # 使用PIL加载和调整图片大小
                        from PIL import Image, ImageTk
                        image = Image.open(image_path)
                        image = image.resize((80, 80), Image.Resampling.LANCZOS)
                        photo = ImageTk.PhotoImage(image)
                        
                        # 在主线程中更新UI
                        self.window.after(0, lambda: self.update_image_frame(image_frame, photo, placeholder_label))
                        return
                    except Exception as e:
                        self.logger.error(f"加载图片失败: {str(e)}")
            except Exception as e:
                self.logger.error(f"获取缓存图片失败: {str(e)}")
            
            # 保持显示占位符
            self.logger.info(f"无法加载图片: {package_name}")
        
        # 在后台线程中加载图片
        threading.Thread(target=load_image, daemon=True).start()
    
    def update_image_frame(self, image_frame: ttk.Frame, photo, placeholder_label):
        """更新图片框架"""
        placeholder_label.destroy()
        
        image_label = ttk.Label(image_frame, image=photo)
        image_label.image = photo  # 保持引用
        image_label.pack(expand=True)
    
    def show_edit_package_dialog(self, package_name: str):
        """显示编辑包对话框"""
        package_info = self.download_manager.get_package_info(package_name)
        if package_info:
            show_edit_package_dialog(
                self.root, self.config, self.download_manager, self.auth_manager,
                package_name, package_info, self.on_package_updated
            )
    
    def on_package_updated(self, success: bool):
        """包更新回调"""
        if success:
            self.refresh_file_list()
    
    def show_package_detail_page(self, package_name: str, from_back: bool = False):
        """显示包详情页面"""
        if not from_back:
            self.push_to_history(package_name)
        
        # 检查是否已存在该页面
        for i in range(self.notebook.index("end")):
            tab_text = self.notebook.tab(i, "text")
            if tab_text.startswith(package_name):
                self.notebook.select(i)
                return
        
        # 创建新页面
        detail_frame = ttk.Frame(self.notebook)
        tab_text = f"{package_name} ×"
        self.notebook.add(detail_frame, text=tab_text)
        self.notebook.select(self.notebook.index("end") - 1)
        
        # 包信息显示
        info_frame = ttk.Frame(detail_frame)
        info_frame.pack(fill=tk.X, padx=10, pady=10)
        
        # 包名称
        ttk.Label(info_frame, text=package_name, font=("Arial", 16, "bold")).pack(anchor=tk.W)
        
        # 获取包详细信息
        package_info = self.download_manager.get_package_info(package_name)
        if package_info:
            # 包简介
            ttk.Label(info_frame, text=package_info.description, wraplength=800, font=("Arial", 10)).pack(anchor=tk.W, pady=(5, 0))
        
        # 版本列表
        versions_frame = ttk.Frame(detail_frame)
        versions_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        ttk.Label(versions_frame, text="版本列表:", font=("Arial", 14, "bold")).pack(anchor=tk.W)
        
        # 版本列表容器
        version_list_container = ttk.Frame(versions_frame)
        version_list_container.pack(fill=tk.BOTH, expand=True, pady=(5, 0))
        
        # 显示版本列表
        self.refresh_version_list(version_list_container, package_name)
    
    def refresh_version_list(self, parent, package_name: str, keyword: str = ""):
        """刷新版本列表"""
        # 清空现有内容
        for widget in parent.winfo_children():
            widget.destroy()
        
        # 获取包信息
        package_info = self.download_manager.get_package_info(package_name)
        if not package_info:
            ttk.Label(parent, text="无法加载包信息").pack(expand=True)
            return
        
        # 获取版本列表
        versions = list(package_info.versions.items())
        
        if not versions:
            ttk.Label(parent, text="没有找到版本").pack(expand=True)
            return
        
        # 创建滚动框架
        canvas = tk.Canvas(parent)
        scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        # 显示版本列表
        for i, (version, version_info) in enumerate(versions):
            self.create_version_item(scrollable_frame, package_name, version, version_info, i)
        
        # 布局
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    def create_version_item(self, parent, package_name: str, version: str, version_info, index: int):
        """创建版本项"""
        item_frame = ttk.Frame(parent, relief=tk.RAISED, borderwidth=1)
        item_frame.pack(fill=tk.X, padx=5, pady=2)
        
        # 版本信息
        info_frame = ttk.Frame(item_frame)
        info_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5, pady=5)
        
        # 版本号
        version_label = ttk.Label(info_frame, text=version, font=("Arial", 12, "bold"))
        version_label.pack(anchor=tk.W)
        
        # 版本简述
        brief_label = ttk.Label(info_frame, text=version_info.brief, font=("Arial", 10))
        brief_label.pack(anchor=tk.W)
        
        # 文件信息
        file_info = f"文件: {version_info.file_name} ({self.format_file_size(version_info.file_size)})"
        file_label = ttk.Label(info_frame, text=file_info, font=("Arial", 9))
        file_label.pack(anchor=tk.W)
        
        # 上传时间
        time_label = ttk.Label(info_frame, text=f"上传: {version_info.upload_time}", font=("Arial", 9))
        time_label.pack(anchor=tk.W)
        
        # 操作按钮
        button_frame = ttk.Frame(item_frame)
        button_frame.pack(side=tk.RIGHT, padx=5, pady=5)
        
        # 详情按钮
        detail_button = ttk.Button(
            button_frame,
            text="详情",
            command=lambda: self.show_version_detail(package_name, version, version_info)
        )
        detail_button.pack(pady=2, fill=tk.X)
        
        # 下载按钮
        download_button = ttk.Button(
            button_frame,
            text="下载",
            command=lambda: self.download_version(package_name, version, version_info)
        )
        download_button.pack(pady=2, fill=tk.X)
        
        # 更改按钮（需要权限）
        if self.auth_manager.has_upload_permission():
            edit_button = ttk.Button(
                button_frame,
                text="更改",
                command=lambda: self.show_edit_version_dialog(package_name, version, version_info)
            )
            edit_button.pack(pady=2, fill=tk.X)
    
    def show_edit_version_dialog(self, package_name: str, version: str, version_info):
        """显示编辑版本对话框"""
        self.version_dialogs.show_edit_version_dialog(
            package_name, version, version_info, self.on_version_updated
        )
    
    def on_version_updated(self, success: bool):
        """版本更新回调"""
        if success:
            messagebox.showinfo("成功", "版本更新成功")
            # 刷新当前包详情页面
            current_index = self.notebook.index("current")
            if current_index > 1:  # 不是前两个固定页面
                current_tab = self.notebook.tab(current_index, "text")
                if " ×" in current_tab:
                    package_name = current_tab.replace(" ×", "")
                    self.show_package_detail_page(package_name, from_back=True)
    
    def create_new_version(self, package_name: str):
        """创建新版本"""
        self.version_dialogs.show_create_version_dialog(
            package_name, self.on_version_created
        )
    
    def on_version_created(self, success: bool):
        """版本创建回调"""
        if success:
            messagebox.showinfo("成功", "版本创建成功")
            # 刷新当前包详情页面
            current_index = self.notebook.index("current")
            if current_index > 1:  # 不是前两个固定页面
                current_tab = self.notebook.tab(current_index, "text")
                if " ×" in current_tab:
                    package_name = current_tab.replace(" ×", "")
                    self.show_package_detail_page(package_name, from_back=True)
    
    def download_version(self, package_name: str, version: str, version_info):
        """下载版本文件"""
        # 弹出保存文件对话框
        from tkinter import filedialog
        filename = filedialog.asksaveasfilename(
            title="保存文件",
            initialfile=version_info.file_name,
            defaultextension=".*"
        )
        if filename:
            self.on_download_version(package_name, version, filename)
    
    def refresh_download_status(self):
        """刷新下载状态"""
        # 清空现有内容
        for widget in self.download_status_frame.winfo_children():
            widget.destroy()
        
        # 下载状态标题
        ttk.Label(
            self.download_status_frame, 
            text="下载状态",
            font=("Arial", 16, "bold")
        ).pack(anchor=tk.W, pady=(0, 10))
        
        # 创建选项卡显示不同状态
        status_notebook = ttk.Notebook(self.download_status_frame)
        status_notebook.pack(fill=tk.BOTH, expand=True)
        
        # 正在下载标签页
        downloading_frame = ttk.Frame(status_notebook)
        status_notebook.add(downloading_frame, text="正在下载")
        
        # 已完成标签页
        completed_frame = ttk.Frame(status_notebook)
        status_notebook.add(completed_frame, text="已完成")
        
        # 显示正在下载的任务
        self.refresh_downloading_tasks(downloading_frame)
        
        # 显示已完成的任务
        self.refresh_completed_tasks(completed_frame)
    
    def refresh_downloading_tasks(self, parent):
        """刷新正在下载的任务"""
        if not self.download_tasks:
            ttk.Label(parent, text="没有正在下载的任务").pack(expand=True)
            return
        
        # 创建滚动框架
        canvas = tk.Canvas(parent)
        scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        for task in self.download_tasks:
            self.create_download_task_item(scrollable_frame, task, "downloading")
        
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    def refresh_completed_tasks(self, parent):
        """刷新已完成的任务"""
        if not self.completed_tasks:
            ttk.Label(parent, text="没有已完成的任务").pack(expand=True)
            return
        
        # 创建滚动框架
        canvas = tk.Canvas(parent)
        scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        for task in self.completed_tasks:
            self.create_download_task_item(scrollable_frame, task, "completed")
        
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    def create_download_task_item(self, parent, task, status):
        """创建下载任务项"""
        item_frame = ttk.Frame(parent, relief=tk.RAISED, borderwidth=1)
        item_frame.pack(fill=tk.X, padx=5, pady=2)
        
        # 任务信息
        info_frame = ttk.Frame(item_frame)
        info_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5, pady=5)
        
        # 文件名
        file_name = task.get("file_name", "未知文件")
        name_label = ttk.Label(info_frame, text=file_name, font=("Arial", 10, "bold"))
        name_label.pack(anchor=tk.W)
        
        # 状态
        status_text = "下载中..." if status == "downloading" else "已完成"
        status_label = ttk.Label(info_frame, text=f"状态: {status_text}", font=("Arial", 9))
        status_label.pack(anchor=tk.W)
        
        # 进度信息
        if status == "downloading":
            progress = ttk.Progressbar(info_frame, mode='indeterminate')
            progress.pack(fill=tk.X, pady=(5, 0))
            progress.start()
        
        # 操作按钮
        button_frame = ttk.Frame(item_frame)
        button_frame.pack(side=tk.RIGHT, padx=5, pady=5)
        
        if status == "completed":
            # 删除按钮
            delete_button = ttk.Button(
                button_frame,
                text="删除",
                command=lambda t=task: self.delete_completed_task(t)
            )
            delete_button.pack(pady=2, fill=tk.X)
    
    def delete_completed_task(self, task):
        """删除已完成的任务"""
        if task in self.completed_tasks:
            self.completed_tasks.remove(task)
            self.refresh_download_status()
            self.logger.info(f"已删除下载任务: {task.get('file_name')}")
    
    def add_download_task(self, package_name: str, version: str, save_path: str):
        """添加下载任务"""
        task = {
            "package_name": package_name,
            "version": version,
            "file_name": f"{package_name}_{version}",
            "save_path": save_path,
            "status": "downloading"
        }
        self.download_tasks.append(task)
        self.refresh_download_status()
        
        return task
    
    def complete_download_task(self, task, success: bool):
        """完成下载任务"""
        if task in self.download_tasks:
            self.download_tasks.remove(task)
            task["status"] = "completed" if success else "failed"
            task["success"] = success
            self.completed_tasks.append(task)
            self.refresh_download_status()
    
    def sync_data(self):
        """同步数据"""
        self.download_manager.sync_with_remote(self.on_sync_complete)
    
    def on_sync_complete(self, success: bool):
        """同步完成回调"""
        if success:
            self.refresh_file_list()
        else:
            messagebox.showerror("错误", "数据同步失败")
    
    def show_version_detail(self, package_name: str, version: str, version_info):
        """显示版本详情"""
        self.version_dialogs.show_version_detail_dialog(
            package_name, version, version_info, self.on_download_version
        )
    
    def on_download_version(self, package_name: str, version: str, save_path: str):
        """下载版本回调"""
        # 添加下载任务
        task = self.add_download_task(package_name, version, save_path)
        
        def download_task():
            self.download_manager.download_version_file(
                package_name, version, save_path, 
                lambda success: self.on_download_complete(task, success)
            )
        
        threading.Thread(target=download_task, daemon=True).start()
    
    def on_download_complete(self, task, success: bool):
        """下载完成回调"""
        self.complete_download_task(task, success)
        
        if success:
            messagebox.showinfo("成功", "文件下载完成")
            self.logger.info(f"文件下载完成: {task.get('file_name')}")
        else:
            messagebox.showerror("错误", "文件下载失败")
            self.logger.error(f"文件下载失败: {task.get('file_name')}")
    
    def format_file_size(self, size_bytes: int) -> str:
        """格式化文件大小显示"""
        if not size_bytes:
            return "未知大小"
        
        try:
            size_bytes = int(size_bytes)
            if size_bytes == 0:
                return "0 B"
            
            units = ['B', 'KB', 'MB', 'GB']
            size = float(size_bytes)
            unit_index = 0
            
            while size >= 1024 and unit_index < len(units) - 1:
                size /= 1024
                unit_index += 1
            
            return f"{size:.1f} {units[unit_index]}"
        except (ValueError, TypeError):
            return "未知大小"